#pragma once
#include<iostream>
#include<functional>
namespace ylz
{
    template <class T>
    class shared_ptr
    {
    public:
        explicit shared_ptr(T* ptr = nullptr)//普通的构造
        :_ptr(ptr)
        {
            (*_pcount)++;
        }


        template <class D>
        explicit shared_ptr(T* ptr,D del)//支持删除器的构造C++中默认参数必须在末尾
        :_ptr(ptr),_del(del)
        {
            (*_pcount)++;
        }


        shared_ptr(const shared_ptr<T>& ptr)
        :_ptr(ptr._ptr),_pcount(ptr._pcount),_del(ptr._del)
        {
            (*_pcount)++;
        }


        void release()//释放资源
        {
            if(--(*_pcount) == 0)
            {
                _del(_ptr);
                delete _pcount;
                _ptr = nullptr;
                _pcount = nullptr;
                _del = nullptr; 

            }
        }


        shared_ptr<T>& operator=(const shared_ptr<T>& sp)
        {
            if(this != sp)//判断一下是不是自己给自己复值
            {
                release();//与自己原有的资源解除关系
                _ptr = sp._ptr;
                _pcount = sp._pcount;
                _del = sp._del;
                ++(*_pcount);

            }
            return *this;
        }

        ~shared_ptr()
        {
            release();
        }

        T& operator*()
        {
            return *_ptr;
        }

        T* operator->()
        {
            return _ptr;
        }

        T* get() const
        {
            return _ptr;
        }
        int use_count()const
        {
            return *_pcount;
        }

        operator bool()
        {
            return _ptr != nullptr;
        }

    private:
        T* _ptr;
        int* _pcount = new int(0);
        std::function<void(T*)> _del = [](T* ptr){delete ptr;};
    };
}